///////////////////////////////////////////////////////////////////////////////
// Name:        profiling.cpp
// Purpose:     Profiling functions
// Copyright:   (c) 2006, Ivan Laptev, TT Solutions
// License:     GPL, Please contact us for commercial license.
//              http://www.tt-solutions.com/
///////////////////////////////////////////////////////////////////////////////
#include "objectdet/profiling.h"

#define PROFILE 1

#include <list>

using namespace std;

typedef pair<string, int64> TickInfo;
typedef list<TickInfo> TicksInfo;
static TicksInfo ticks_info;

static void ShowTickSummary();

// timer helper
IMPEXP
void Tick(char const * label)
{
    (void)label;
#if PROFILE
    static bool ticks_atexit_registered = false;
    if (!ticks_atexit_registered)
    {
        atexit(ShowTickSummary);
        ticks_atexit_registered = true;
    }
    cout << "Tick(" << label << ")\n" << flush;
    ticks_info.push_back( TickInfo(label, cvGetTickCount()) );
#endif
}

void ShowTickSummary()
{
#if PROFILE
    if (ticks_info.empty())
        return;

    std::size_t max_label_width = 0;
    TicksInfo::const_iterator cit;
    for (cit = ticks_info.begin(); cit != ticks_info.end(); ++cit)
    {
        if (max_label_width < cit->first.size())
            max_label_width = cit->first.size();
    }

    int64 first_tick = ticks_info.begin()->second;
    int64 total_ticks = ticks_info.back().second - first_tick;

    if (total_ticks == 0)
        total_ticks = 1;

    cout << "Profiling information:\n";

    int64 previous_tick = first_tick;

    double tick_frequency = cvGetTickFrequency() * (double)1000 * (double)1000;
    for (TicksInfo::const_iterator cit = ticks_info.begin(); cit != ticks_info.end(); ++cit)
    {
        char const * label = cit->first.c_str();
        int64 const tick = cit->second;
		cout.width(static_cast<std::streamsize>(max_label_width));
        cout << left << label;

        cout << " | ";
        cout.precision( 2 );
        cout.width(7);
        cout << fixed << right << (100 * (double)(tick - previous_tick) / (double)total_ticks) << "%";

        cout << " | ";
        cout.precision( 2 );
        cout.width(7);
        cout << fixed << right << ((double)(tick - previous_tick) / tick_frequency) << "s";

        cout << " | ";
        cout.precision( 2 );
        cout.width(7);
        cout << fixed << right << (100 * (double)(tick - first_tick) / (double)total_ticks) << "%";

        previous_tick = tick;
        cout << "\n";
    }
#endif
}

